

#include <Ogre.h>
#include <OIS/OIS.h>
#include "OgreInterface.h"

using namespace Ogre;


class MouseLookListener : public FrameListener, public WindowEventListener {
    Camera *camera;
    RenderWindow *window;
    OIS::InputManager *inputManager;
    OIS::Mouse *mouse;
    Vector3 translateVector;
    float moveScale;
    Real moveSpeed;
    Degree rotationScale, rotationSpeed;
    Radian rotX, rotY;

public:
    MouseLookListener( Camera* cameraArg, RenderWindow *windowArg );
    bool frameStarted (const FrameEvent &evt);
    bool frameEnded (const FrameEvent &evt);
};


/**
 *Constructor of the frame listener
 * @window : pointer to the main window of the application
 */
MouseLookListener::MouseLookListener( Camera *cameraArg, RenderWindow *windowArg ) {

    camera = cameraArg;
    window = windowArg;

    //initialize input for mouse
    OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;
    window->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
    inputManager = OIS::InputManager::createInputSystem(pl);

    mouse = static_cast<OIS::Mouse*>(inputManager->createInputObject(OIS::OISMouse, false));
}

/**
 * This method adds events to the render loop that occur
 * before each frame is rendered.
 */
bool MouseLookListener::frameStarted(const FrameEvent &evt) {

    using namespace OIS;
    //Real MoveFactor = 60.0 * evt.timeSinceLastFrame;

    mouse->capture();

    moveScale = moveSpeed * evt.timeSinceLastFrame;
    rotationScale = rotationSpeed * evt.timeSinceLastFrame;

    rotX = 0;
    rotY = 0;
    translateVector = Ogre::Vector3::ZERO;


    const MouseState &ms = mouse->getMouseState();
    if( ms.buttonDown( MB_Right ) ) {
        translateVector.x += ms.X.rel * 0.13;
        translateVector.y -= ms.Y.rel * 0.13;
    }
    else {
        rotX = Degree(-ms.X.rel * 0.13);
        rotY = Degree(-ms.Y.rel * 0.13);
    }

    this->camera->yaw(rotX);
    this->camera->pitch(rotY);
    this->camera->moveRelative(translateVector);




/*
    // Move the camera around with the left button
    if (inputDevice->getMouseButton(1)) {
        SceneNode *camNode = camera->getParentSceneNode();

        if (camNode == 0) {
            std::cerr << "mCamera isn't attached to any SceneNode !" << std::endl;
        }

        camNode->yaw(Degree(inputDevice->getMouseRelativeX() * MoveFactor * -0.1));
        camNode->pitch(Degree(inputDevice->getMouseRelativeY() * MoveFactor * -0.1));
    }

    // Zoom with the middle button...
    if (inputDevice->getMouseButton(2)) {
        camera->moveRelative(Vector3(0.0, 0.0, -0.5)
            * inputDevice->getMouseRelativeY() * MoveFactor);
    }
    // ... and the wheel ;-)
    camera->moveRelative(Vector3(0.0, 0.0, -0.1)
        * inputDevice->getMouseRelativeZ() * MoveFactor);
*/
    return true;
}

/**
 * This method adds events to the render loop that occur
 * after each frame is rendered.
 */
bool MouseLookListener::frameEnded(const FrameEvent &evt) {
    return true;
}













bool OgreInterface::activateMouseLookListener( ) {

    if ( (mainCam == NULL) || (window == NULL) ) {
        return false;
    }

    //Create a frame listener to handle window closing
    FrameListener *mouseLookListener = new MouseLookListener( this->mainCam, this->window );
    //listener->setWindow( window );
    this->root->addFrameListener( mouseLookListener );

    return true;
}
